﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NSDecisionTree.Graphic
{
    public class Graph
    {
        Node rootNode;
        List<int> levelItemsCount;

        public Graph()
        {
            rootNode = new Node("",0);
            levelItemsCount = new List<int>();
        }

        public List<int> LevelItemsCount
        {
            get { return levelItemsCount; }
        }

        internal Node RootNode
        {
            get { return rootNode; }
        }

        internal void CreateGraph(DTree.Tree completeTree)
        {
            ArrayList[] domains = completeTree.Domains;
            int numAttributes = completeTree.NumAttributes;
            DTree.TreeNode rootTreeNode = completeTree.Root;

            rootNode = new Node(rootTreeNode.Name, rootTreeNode.Entropy);
            // rootNode
            levelItemsCount.Add(1);
            
            foreach (DTree.TreeNode child in rootTreeNode.Children)
            {
                ExportChilds(domains, numAttributes, completeTree, rootNode, child);
            }
       }

        private void ExportChilds(ArrayList[] domains, int numAttributes, DTree.Tree completeTree, Node rootNode, DTree.TreeNode child)
        {
            int levelIndex = rootNode.Level + 1;
            if (levelItemsCount.Count - 1 < levelIndex)
            {
                levelItemsCount.Add(1);
            }
            else
            {
                int newValue = levelItemsCount.ElementAt(levelIndex) + 1;
                levelItemsCount[levelIndex] = newValue;
            }
            // keine weiteren Kinder vorhanden
            if (child.Children == null)
            {
                int index = 0;
                for (int i = 0; i < child.Parent.Children.Length; i++)
                {
                    if ( child.Equals(child.Parent.Children[i]) )
                    {
                        index = i;
                        break;
                    }
                }
                Edge edgeToLeaf = new Edge(domains[child.Parent.DecompositionAttribute][index].ToString());
                string[] values = completeTree.GetAllStringValues(child.Data, numAttributes - 1);

                String ret = String.Empty;

                for (int i = 0; i < values.Length; i++)
                {
                    ret += values[i].ToString();
                    if (i + 1 < values.Length)
                        ret += ", ";
                }
                Node leaf = new Node(ret, 0);
                rootNode.AddChildNode(leaf, edgeToLeaf, levelItemsCount);
                leaf.SumChildCount = child.Data.Count;
            }
            else
            {
                int index = 0;
                for (int i = 0; i < child.Parent.Children.Length; i++)
                {
                    if (child.Equals(child.Parent.Children[i]))
                    {
                        index = i;
                        break;
                    }
                }

                string forEdge = domains[child.Parent.DecompositionAttribute][index].ToString();
                string forNode = completeTree.AttributeNames[child.DecompositionAttribute];
                Node newRootNode = new Node(forNode, child.Entropy);
                rootNode.AddChildNode(newRootNode, new Edge(forEdge), levelItemsCount);
                foreach (DTree.TreeNode newChild in child.Children)
                {
                    ExportChilds(domains, numAttributes, completeTree, newRootNode, newChild);
                }
            }
        }
    }
}
